
/**
 * 循环队列
 */
 class Queue{
    /**
     * 
     * @param {*} n 队列大小为n
     */
    constructor(n) {
        this.arr = new Array(n)
        this.head = this.tail = 0;
        this.cut = 0 //记录队列中元素的个数
    }
    
}
// 入队
Queue.prototype.enqueue = function(val){
    if(this.full())return;
    this.arr[this.tail] = val
    this.tail += 1; //尾指针向后移动一位 
    if(this.full()) this.tail = 0;
    this.cut += 1; //数量加一
}
// 出队
Queue.prototype.dequeue = function(val){
    if(this.empty())return;
    this.head += 1 //头指针向后移动一位
    if(this.head === this.arr.length) this.head = 0;
    this.cut -= 1; //数量加一
}
// 空队列
Queue.prototype.empty = function(val){
    return this.cut  === 0
}

// 队列满了
Queue.prototype.full = function(val){
    return this.cut === this.arr.length;
}

// 队列中元素个数
Queue.prototype.size = function(val){
    return this.cut
}

// 查看队首元素
Queue.prototype.front = function(val){
    if(this.empty())return;
    return this.arr[this.head]
}

// 清空队列
Queue.prototype.clear = function(val){
    this.head = this.tail = this.cut = 0; 
}

// 打印队列
Queue.prototype.output = function(val){
    let temp = [];
    for (let i = 0,j = this.head; i < this.cut; i++) {
        temp.push(this.arr[j]);
        j++;
        if(j === this.arr.length) j=0;   
    }
    return temp
}


function test(opts, vals) {
    let queue = new Queue(5);
  
    for (let i = 0; i < opts.length; i++) {
      switch (opts[i]) {
        case 'insert':
          queue.enqueue(vals[i]);
          break;
        case 'front':
          console.log(`front element: ${queue.front()}`);
          break;
        case 'dequeue':
          queue.dequeue();
          break;
        case 'size':
          console.log(`queue size: ${queue.size()}`);
          break;
        default:
          break;
      }
      console.log(queue.output());
    }
  }
  
  let opts = ['insert', 'insert', 'insert', 'dequeue', 'insert', 'insert', 'dequeue', 'insert', 'insert'];
  let vals = [1, 2, 3, '', 4, 5, '', 6, 7]
  test(opts, vals)

